import 'dart:ui' as ui;

import 'package:flutter/material.dart';

enum IndicatorAxisAlignment {
  start,
  end,
  center,
}

class ImageIndicator extends Decoration {
  final ui.Image image;
  final Color color;
  final double width;
  final double height;
  final double marginBottom;
  final IndicatorAxisAlignment alignment;

  ImageIndicator(
      {@required this.image,
      this.color,
      this.height,
      this.width,
      this.alignment = IndicatorAxisAlignment.center,
      this.marginBottom = 0});
  @override
  BoxPainter createBoxPainter([VoidCallback? onChanged]) {
    return _ImageIndicatorPaint(this, onChanged);
  }
}

class RoundRectIndicator extends Decoration {
  final Color? color;
  final double? width;
  final double height;
  final double round;
  final double marginBottom;
  RoundRectIndicator(
      {@required this.color,
      this.height = 2,
      this.width,
      this.round = 1,
      this.marginBottom = 0});

  @override
  BoxPainter createBoxPainter([void Function()? onChanged]) {
    return _RoundRectPainter(this, onChanged);
  }
}

class _ImageIndicatorPaint extends BoxPainter {
  final ImageIndicator? dec;
  final VoidCallback? onChanged;
  Paint painter = Paint();

  _ImageIndicatorPaint([this.dec, this.onChanged]) : super() {
    painter.style = PaintingStyle.stroke;
    painter.isAntiAlias = true;
    if (dec?.color != null) {
      painter.colorFilter = ColorFilter.mode(dec!.color!, BlendMode.srcIn);
    }
  }

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration config) async {
    double? width = dec!.width;
    double? height = dec!.height;
    Size iSize = config.size!;
    if (width == null || height == null) {
      width = dec!.image!.width.toDouble();
      height = dec!.image!.height.toDouble();
    }
    // 计算图片绘制中心坐标
    double xAxis = offset.dx;
    double yAxis = offset.dy + iSize.height - height / 2 - dec.marginBottom;
    if (dec.alignment == IndicatorAxisAlignment.center) {
      xAxis = offset.dx + iSize.width / 2;
    } else if (dec.alignment == IndicatorAxisAlignment.end) {
      xAxis = offset.dx + iSize.width;
    }
    Offset centerOffset = Offset(xAxis, yAxis);

    Rect rect =
        Rect.fromCenter(center: centerOffset, width: width, height: height);

    canvas.drawImageNine(dec!.image!, rect, rect, painter);
  }
}

class _RoundRectPainter extends BoxPainter {
  final RoundRectIndicator? dec;
  final VoidCallback? onChanged;
  Paint painter = Paint();

  _RoundRectPainter([this.dec, this.onChanged]) : super() {
    painter.style = PaintingStyle.fill;
    painter.isAntiAlias = true;
    if (dec?.color != null) {
      painter.colorFilter = ColorFilter.mode(dec!.color!, BlendMode.srcIn);
    }
  }

  @override
  void paint(Canvas canvas, Offset offset, ImageConfiguration config) async {
    Rect rect = _indicatorRectFor(offset & config.size!, config.textDirection!);
    RRect rRect = RRect.fromRectAndRadius(rect, Radius.circular(dec!.round));
    canvas.drawRRect(rRect, painter);
  }

  Rect _indicatorRectFor(Rect rect, TextDirection textDirection) {
    Rect indicator = EdgeInsets.zero.resolve(textDirection).deflateRect(rect);
    double? width = dec?.width;
    double left = indicator.left;
    if (width == null) {
      width = indicator.width;
    } else {
      left += (indicator.width - width) / 2;
    }
    return Rect.fromLTWH(
      left,
      indicator.bottom - dec!.height - dec!.marginBottom,
      width,
      dec!.height,
    );
  }
}
